package com.quiz.bis.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.quiz.bis.domain.bo.*;
import com.quiz.bis.domain.model.*;
import com.quiz.bis.domain.vo.*;
import com.quiz.bis.mapper.*;
import com.quiz.bis.service.IPaperGenerateService;
import com.quiz.common.core.domain.R;
import com.quiz.common.exception.ServiceException;
import com.quiz.common.mybatis.core.query.PlusWrappers;
import com.quiz.common.utils.SecurityUtils;
import com.quiz.common.utils.StringUtils;
import com.quiz.common.utils.bean.BeanUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class PaperGenerateServiceImpl implements IPaperGenerateService {

    private final PaperMapper paperMapper;
    private final PaperQuestionMapper paperQuestionMapper;
    private final PaperTemplateMapper paperTemplateMapper;
    private final PaperStrategyMapper paperStrategyMapper;
    private final QuestionMapper questionMapper;
    private final QuestionStatisticsMapper questionStatisticsMapper;
    private final QuestionCategoryRelationMapper questionCategoryRelationMapper;
    private final QuestionTagRelationMapper questionTagRelationMapper;
    private final TagMapper tagMapper;
    private final QuestionCategoryMapper questionCategoryMapper;

    // 线程池用于异步执行遗传算法
    private final ExecutorService executorService = Executors.newFixedThreadPool(4);

    @Override
    @Transactional
    public PaperGenerateResult autoGeneratePaper(PaperGenerateRequest request) {
        long startTime = System.currentTimeMillis();
        PaperGenerateResult result;

        try {
            if (Boolean.TRUE.equals(request.getUseGenetic())) {
                // 尝试遗传算法组卷
                result = geneticGeneratePaper(request);

                // 如果遗传算法失败且配置允许降级，则使用模板组卷
                if (!result.getSuccess() && request.getGeneticConfig() != null
                        && request.getGeneticConfig().getFallbackToTemplate()) {
                    log.warn("Genetic algorithm failed, fallback to template generation");
                    result = templateGeneratePaper(request);
                    result.setMessage("遗传算法组卷失败，已降级使用模板组卷");
                }
            } else {
                // 直接使用模板组卷
                result = templateGeneratePaper(request);
            }
        } catch (Exception e) {
            log.error("Paper generation failed", e);
            result = new PaperGenerateResult();
            result.setSuccess(false);
            result.setMessage("组卷失败: " + e.getMessage());
        }

        result.setTimeCost(System.currentTimeMillis() - startTime);
        return result;
    }

    @Override
    @Transactional
    public PaperGenerateResult templateGeneratePaper(PaperGenerateRequest request) {
        PaperGenerateResult result = new PaperGenerateResult();
        result.setIsGenetic(false);

        try {
            // 1. 验证模板
            PaperTemplate template = paperTemplateMapper.selectById(request.getTemplateId());
            if (template == null || template.getDelFlag() == 1) {
                throw new ServiceException("模板不存在或已删除");
            }

            // 2. 解析模板配置
            Map<String, Object> config = parseTemplateConfig(template.getConfigJson());

            // 3. 根据模板配置查询题目
            List<Question> questions = selectQuestionsByTemplate(config);

            // 4. 创建试卷
            PaperBO paperBO = createPaperBO(request, questions, config);
            R<Long> createResult = createPaper(paperBO);

            if (!R.isSuccess(createResult)) {
                throw new ServiceException(createResult.getMsg());
            }

            result.setPaperId(createResult.getData());
            result.setSuccess(true);
            result.setMessage("使用模板成功组卷");
        } catch (Exception e) {
            result.setSuccess(false);
            result.setMessage("模板组卷失败: " + e.getMessage());
        }

        return result;
    }

    @Override
    public PaperGenerateResult geneticGeneratePaper(PaperGenerateRequest request) {
        PaperGenerateResult result = new PaperGenerateResult();
        result.setIsGenetic(true);

        try {
            // 1. 验证策略
            PaperStrategy strategy = paperStrategyMapper.selectById(request.getStrategyId());
            if (strategy == null || strategy.getDelFlag() == 1) {
                throw new ServiceException("策略不存在或已删除");
            }

            // 2. 解析策略配置
            Map<String, Object> difficultyConfig = parseDifficultyConfig(strategy.getDifficultyConfig());
            JSONObject knowledgeConfig = parseKnowledgeConfig(strategy.getKnowledgeConfig());
            Map<String, Object> questionConfig = parseQuestionConfig(strategy.getQuestionConfig());

            // 3. 获取遗传算法配置
            GeneticAlgorithmConfig gaConfig = request.getGeneticConfig() != null ?
                    request.getGeneticConfig() : getDefaultGAConfig(strategy);

            // 4. 异步执行遗传算法
            Future<PaperGenerateResult> future = executorService.submit(() ->
                    runGeneticAlgorithm(request, difficultyConfig, knowledgeConfig, questionConfig, gaConfig));

            // 5. 等待结果，带超时
            try {
                result = future.get(gaConfig.getTimeLimit(), TimeUnit.SECONDS);
            } catch (TimeoutException e) {
                future.cancel(true);
                throw new ServiceException("遗传算法执行超时");
            } catch (Exception e) {
                throw new ServiceException("遗传算法执行失败: " + e.getMessage());
            }

        } catch (Exception e) {
            result.setSuccess(false);
            result.setMessage("遗传算法组卷失败: " + e.getMessage());
        }

        return result;
    }

    private PaperGenerateResult runGeneticAlgorithm(PaperGenerateRequest request,
                                                    Map<String, Object> difficultyConfig, JSONObject knowledgeConfig,
                                                    Map<String, Object> questionConfig, GeneticAlgorithmConfig gaConfig) {

        PaperGenerateResult result = new PaperGenerateResult();
        result.setIsGenetic(true);

        try {
            // 1. 初始化种群
            List<PaperChromosome> population = initializePopulation(questionConfig, gaConfig.getPopulationSize());

            // 2. 进化过程
            int generation = 0;
            double bestFitness = 0;
            int stagnationCount = 0;
            boolean success = false;

            while (generation < gaConfig.getMaxGenerations() && !success) {
                // 评估适应度
                evaluatePopulation(population, difficultyConfig, knowledgeConfig, questionConfig);

                // 找出当前最优个体
                PaperChromosome best = Collections.max(population,
                        Comparator.comparingDouble(PaperChromosome::getFitness));

                // 检查终止条件
                if (best.getFitness() >= gaConfig.getFitnessThreshold()) {
                    success = true;
                    bestFitness = best.getFitness();
                    break;
                }

                // 检查适应度平台期
                if (Math.abs(best.getFitness() - bestFitness) < 0.01) {
                    stagnationCount++;
                    if (stagnationCount >= 5) {
                        break; // 连续5代没有明显改进，停止进化
                    }
                } else {
                    stagnationCount = 0;
                    bestFitness = best.getFitness();
                }

                // 选择、交叉、变异
                population = evolvePopulation(population, gaConfig);
                generation++;
            }

            // 3. 获取最终最优个体
            evaluatePopulation(population, difficultyConfig, knowledgeConfig, questionConfig);
            PaperChromosome best = Collections.max(population,
                    Comparator.comparingDouble(PaperChromosome::getFitness));

            // 4. 创建试卷
            if (best.getFitness() >= gaConfig.getFitnessThreshold() * 0.8) { // 允许部分妥协
                PaperBO paperBO = createPaperBO(request, best.getQuestions(), questionConfig);
                R<Long> createResult = createPaper(paperBO);

                if (R.isSuccess(createResult)) {
                    result.setPaperId(createResult.getData());
                    result.setSuccess(true);
                    result.setGeneration(generation);
                    result.setFitness(best.getFitness());
                    result.setMessage(String.format("遗传算法组卷成功，迭代%d代，适应度%.2f",
                            generation, best.getFitness()));
                } else {
                    throw new ServiceException(createResult.getMsg());
                }
            } else {
                throw new ServiceException("无法找到满足条件的试卷组合，最佳适应度: " + best.getFitness());
            }

        } catch (Exception e) {
            result.setSuccess(false);
            result.setMessage("遗传算法执行失败: " + e.getMessage());
        }

        return result;
    }

    // 初始化种群
    private List<PaperChromosome> initializePopulation(Map<String, Object> questionConfig, int populationSize) {
        List<PaperChromosome> population = new ArrayList<>();

        // 获取所有符合条件的题目
        List<Question> allQuestions = selectQuestionsByQuestionConfig(questionConfig);

        // 生成初始种群
        for (int i = 0; i < populationSize; i++) {
            PaperChromosome chromosome = new PaperChromosome();

            // 随机选择题目组成试卷
            List<Question> paperQuestions = new ArrayList<>();
            Map<Long, Integer> typeCounts = new HashMap<>();
            Map<Long, BigDecimal> typeScores = new HashMap<>();

            // 解析题型配置
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> typeConfigs = (List<Map<String, Object>>) questionConfig.get("types");

            for (Map<String, Object> typeConfig : typeConfigs) {
                Long typeId = Long.valueOf((Integer) typeConfig.get("typeId"));
                String typeName = (String) typeConfig.get("name");
                int count = (int) typeConfig.get("count");
                BigDecimal score = new BigDecimal(typeConfig.get("score").toString());

                typeCounts.put(typeId, count);
                typeScores.put(typeId, score);
            }

            // 按题型随机选择题目
            for (Map.Entry<Long, Integer> entry : typeCounts.entrySet()) {
                Long typeId = entry.getKey();
                int count = entry.getValue();
                BigDecimal score = typeScores.get(typeId);

                // 获取该题型的所有题目
                List<Question> typeQuestions = allQuestions.stream()
                        .filter(q -> typeId.equals(q.getTypeId()))
                        .collect(Collectors.toList());

                if (typeQuestions.size() < count) {
                    throw new ServiceException("题型" + typeId + "的题目数量不足");
                }

                // 随机选择题目
                Collections.shuffle(typeQuestions);
                List<Question> selected = typeQuestions.subList(0, count);

                // 设置题目分数
                selected.forEach(q -> {
                    Question questionWithScore = new Question();
                    BeanUtils.copyProperties(q, questionWithScore);
                    questionWithScore.setScore(score);
                    paperQuestions.add(questionWithScore);
                });
            }

            chromosome.setQuestions(paperQuestions);
            population.add(chromosome);
        }

        return population;
    }

    // 评估种群适应度
    private void evaluatePopulation(List<PaperChromosome> population,
                                    Map<String, Object> difficultyConfig,
                                    JSONObject knowledgeConfig,
                                    Map<String, Object> questionConfig) {

        // 并行计算适应度
        population.parallelStream().forEach(chromosome -> {
            double fitness = calculateFitness(chromosome.getQuestions(),
                    difficultyConfig, knowledgeConfig, questionConfig);
            chromosome.setFitness(fitness);
        });
    }

    // 计算适应度
    private double calculateFitness(List<Question> questions,
                                    Map<String, Object> difficultyConfig,
                                    JSONObject knowledgeConfig,
                                    Map<String, Object> questionConfig) {

        double fitness = 0;
        int factorCount = 0;

        // 1. 难度匹配度
        if (difficultyConfig != null && !difficultyConfig.isEmpty()) {
            double difficultyFitness = calculateDifficultyFitness(questions, difficultyConfig);
            fitness += difficultyFitness;
            factorCount++;
        }

        // 2. 知识点覆盖度
        if (knowledgeConfig != null && !knowledgeConfig.isEmpty()) {
            double knowledgeFitness = calculateKnowledgeFitness(questions, knowledgeConfig);
            fitness += knowledgeFitness;
            factorCount++;
        }

        // 3. 题型分布匹配度
        if (questionConfig != null && questionConfig.containsKey("types")) {
            double typeFitness = calculateTypeFitness(questions, questionConfig);
            fitness += typeFitness;
            factorCount++;
        }

        // 4. 题目重复率惩罚
        double repeatPenalty = calculateRepeatPenalty(questions);
        fitness -= repeatPenalty;

        // 5. 题目质量加分(使用次数、正确率等)
        double qualityBonus = calculateQualityBonus(questions);
        fitness += qualityBonus;

        // 计算平均适应度
        if (factorCount > 0) {
            fitness /= factorCount;
        }

        return Math.max(0, Math.min(1, fitness)); // 确保在0-1之间
    }

    // 计算难度适应度
    private double calculateDifficultyFitness(List<Question> questions, Map<String, Object> difficultyConfig) {
        // 计算实际难度分布
        Map<Integer, Integer> actualDistribution = questions.stream()
                .collect(Collectors.groupingBy(Question::getDifficult, Collectors.summingInt(q -> 1)));

        // 获取目标难度分布
        Map<Integer, Double> targetDistribution = new HashMap<>();
        for (Map.Entry<String, Object> entry : difficultyConfig.entrySet()) {
            if (entry.getKey().startsWith("difficulty_")) {
                int level = Integer.parseInt(entry.getKey().substring(11));
                targetDistribution.put(level, Double.parseDouble(entry.getValue().toString()));
            }
        }

        // 计算匹配度
        double matchScore = 0;
        for (Map.Entry<Integer, Double> entry : targetDistribution.entrySet()) {
            int level = entry.getKey();
            double targetRatio = entry.getValue();
            double actualRatio = actualDistribution.getOrDefault(level, 0) / (double) questions.size();

            matchScore += 1 - Math.abs(targetRatio - actualRatio);
        }

        return matchScore / targetDistribution.size();
    }

    // 计算知识点适应度
    private double calculateKnowledgeFitness(List<Question> questions, JSONObject knowledgeConfig) {
        // 获取所有题目涉及的知识点
        Set<Long> knowledgePoints = new HashSet<>();
        List<Long> questionIds = questions.stream().map(Question::getId).collect(Collectors.toList());

        if (!questionIds.isEmpty()) {
            List<QuestionCategoryRelation> relations = questionCategoryRelationMapper.selectList(
                    Wrappers.<QuestionCategoryRelation>lambdaQuery()
                            .in(QuestionCategoryRelation::getQuestionId, questionIds)
                            .eq(QuestionCategoryRelation::getIsKnowledge, 1)
                            .eq(QuestionCategoryRelation::getDelFlag, 0));

            relations.forEach(r -> knowledgePoints.add(r.getId()));
        }

        // 获取目标知识点
        List<Long> targetPoints = Arrays.stream(knowledgeConfig.getJSONArray("knowledgePoints").toArray()).map(obj -> Long.parseLong(obj.toString())).collect(Collectors.toList());

//        List<Long> targetPoints = (List<Long>) knowledgeConfig.get("knowledgePoints");
        double targetCoverage = knowledgeConfig.containsKey("coverage") ?
                Double.parseDouble(knowledgeConfig.get("coverage").toString()) : 1.0;

        if (targetPoints == null || targetPoints.isEmpty()) {
            return 1.0; // 没有指定知识点要求，得满分
        }

        // 计算覆盖率
        int covered = 0;
        for (Long point : targetPoints) {
            if (knowledgePoints.contains(point)) {
                covered++;
            }
        }

        double actualCoverage = covered / (double) targetPoints.size();
        return actualCoverage >= targetCoverage ? 1.0 : actualCoverage / targetCoverage;
    }

    // 计算题型分布适应度
    private double calculateTypeFitness(List<Question> questions, Map<String, Object> questionConfig) {
        // 计算实际题型分布
        Map<Long, Integer> actualCounts = questions.stream()
                .collect(Collectors.groupingBy(Question::getTypeId, Collectors.summingInt(q -> 1)));

        // 获取目标题型分布
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> typeConfigs = (List<Map<String, Object>>) questionConfig.get("types");
        Map<Long, Integer> targetCounts = new HashMap<>();

        for (Map<String, Object> config : typeConfigs) {
            String typeName = (String) config.get("name");
            Long typeId = Long.valueOf((Integer) config.get("typeId"));
            int count = (int) config.get("count");
            targetCounts.put(typeId, count);
        }

        // 计算匹配度
        double matchScore = 0;
        for (Map.Entry<Long, Integer> entry : targetCounts.entrySet()) {
            Long typeId = entry.getKey();
            int target = entry.getValue();
            int actual = actualCounts.getOrDefault(typeId, 0);

            matchScore += 1 - Math.abs(target - actual) / (double) target;
        }

        return matchScore / targetCounts.size();
    }

    // 计算题目重复惩罚
    private double calculateRepeatPenalty(List<Question> questions) {
        // 检查是否有重复题目
        long distinctCount = questions.stream().map(Question::getId).distinct().count();
        if (distinctCount == questions.size()) {
            return 0; // 没有重复
        }

        // 重复题目越多，惩罚越大
        return (questions.size() - distinctCount) * 0.1;
    }

    // 计算题目质量加分
    private double calculateQualityBonus(List<Question> questions) {
        // 获取题目统计数据
        List<Long> questionIds = questions.stream().map(Question::getId).collect(Collectors.toList());
        Map<Long, QuestionStatistics> statsMap = new HashMap<>();

        if (!questionIds.isEmpty()) {
            List<QuestionStatistics> stats = questionStatisticsMapper.selectList(
                    Wrappers.<QuestionStatistics>lambdaQuery()
                            .in(QuestionStatistics::getQuestionId, questionIds)
                            .eq(QuestionStatistics::getDelFlag, 0));

            stats.forEach(s -> statsMap.put(s.getQuestionId(), s));
        }

        // 计算平均质量分数
        double qualitySum = 0;
        for (Question q : questions) {
            QuestionStatistics stat = statsMap.get(q.getId());
            if (stat != null) {
                // 使用次数越多，正确率越高，质量分数越高
                double usageScore = Math.min(1, stat.getUseCount() / 100.0);
                double correctRate = stat.getCorrectCount() / (double) Math.max(1, stat.getUseCount());
                qualitySum += (usageScore + correctRate) / 2;
            }
        }

        return qualitySum / questions.size() * 0.1; // 质量加分不超过0.1
    }

    // 种群进化
    private List<PaperChromosome> evolvePopulation(List<PaperChromosome> population, GeneticAlgorithmConfig config) {
        List<PaperChromosome> newPopulation = new ArrayList<>();

        // 保留精英(前10%)
        int eliteSize = (int) (population.size() * 0.1);
        population.sort(Comparator.comparingDouble(PaperChromosome::getFitness).reversed());
        newPopulation.addAll(population.subList(0, eliteSize));

        // 选择、交叉、变异
        while (newPopulation.size() < population.size()) {
            // 选择
            PaperChromosome parent1 = selectParent(population);
            PaperChromosome parent2 = selectParent(population);

            // 交叉
            PaperChromosome offspring1 = new PaperChromosome();
            PaperChromosome offspring2 = new PaperChromosome();

            if (Math.random() < config.getCrossoverRate()) {
                crossover(parent1, parent2, offspring1, offspring2);
            } else {
                offspring1.setQuestions(new ArrayList<>(parent1.getQuestions()));
                offspring2.setQuestions(new ArrayList<>(parent2.getQuestions()));
            }

            // 变异
            if (Math.random() < config.getMutationRate()) {
                mutate(offspring1);
            }

            if (Math.random() < config.getMutationRate()) {
                mutate(offspring2);
            }

            newPopulation.add(offspring1);
            if (newPopulation.size() < population.size()) {
                newPopulation.add(offspring2);
            }
        }

        return newPopulation;
    }

    // 选择父代(轮盘赌选择)
    private PaperChromosome selectParent(List<PaperChromosome> population) {
        double totalFitness = population.stream().mapToDouble(PaperChromosome::getFitness).sum();
        double randomFitness = Math.random() * totalFitness;
        double currentSum = 0;

        for (PaperChromosome chromosome : population) {
            currentSum += chromosome.getFitness();
            if (currentSum >= randomFitness) {
                return chromosome;
            }
        }

        return population.get(population.size() - 1);
    }

    // 交叉操作
    private void crossover(PaperChromosome parent1, PaperChromosome parent2,
                           PaperChromosome offspring1, PaperChromosome offspring2) {

        // 按题型分组
        Map<Long, List<Question>> parent1Groups = parent1.getQuestions().stream()
                .collect(Collectors.groupingBy(Question::getTypeId));
        Map<Long, List<Question>> parent2Groups = parent2.getQuestions().stream()
                .collect(Collectors.groupingBy(Question::getTypeId));

        // 对每个题型进行交叉
        List<Question> offspring1Questions = new ArrayList<>();
        List<Question> offspring2Questions = new ArrayList<>();

        for (Long typeId : parent1Groups.keySet()) {
            List<Question> typeQuestions1 = parent1Groups.get(typeId);
            List<Question> typeQuestions2 = parent2Groups.get(typeId);

            // 单点交叉
            int crossoverPoint = (int) (Math.random() * typeQuestions1.size());

            // 子代1: 前半部分来自父代1，后半部分来自父代2
            List<Question> offspring1Type = new ArrayList<>();
            offspring1Type.addAll(typeQuestions1.subList(0, crossoverPoint));
            offspring1Type.addAll(typeQuestions2.subList(crossoverPoint, typeQuestions2.size()));

            // 子代2: 前半部分来自父代2，后半部分来自父代1
            List<Question> offspring2Type = new ArrayList<>();
            offspring2Type.addAll(typeQuestions2.subList(0, crossoverPoint));
            offspring2Type.addAll(typeQuestions1.subList(crossoverPoint, typeQuestions1.size()));

            offspring1Questions.addAll(offspring1Type);
            offspring2Questions.addAll(offspring2Type);
        }

        offspring1.setQuestions(offspring1Questions);
        offspring2.setQuestions(offspring2Questions);
    }

    // 变异操作
    private void mutate(PaperChromosome chromosome) {
        // 随机选择一种变异方式
        double mutationType = Math.random();

        if (mutationType < 0.3) {
            // 30%概率: 替换一道题目
            replaceOneQuestion(chromosome);
        } else if (mutationType < 0.6) {
            // 30%概率: 交换两道题目
            swapTwoQuestions(chromosome);
        } else if (mutationType < 0.9) {
            // 30%概率: 调整题目分数
            adjustQuestionScores(chromosome);
        } else {
            // 10%概率: 打乱题目顺序
            Collections.shuffle(chromosome.getQuestions());
        }
    }

    private void replaceOneQuestion(PaperChromosome chromosome) {
        if (chromosome.getQuestions().isEmpty()) return;

        // 随机选择一道题目
        int index = (int) (Math.random() * chromosome.getQuestions().size());
        Question toReplace = chromosome.getQuestions().get(index);

        // 查找同题型的其他题目
        List<Question> sameTypeQuestions = questionMapper.selectList(
                Wrappers.<Question>lambdaQuery()
                        .eq(Question::getTypeId, toReplace.getTypeId())
                        .eq(Question::getDelFlag, 0)
                        .ne(Question::getId, toReplace.getId()));

        if (!sameTypeQuestions.isEmpty()) {
            // 随机选择一道替换
            Question replacement = sameTypeQuestions.get((int) (Math.random() * sameTypeQuestions.size()));
            replacement.setScore(toReplace.getScore()); // 保持分数不变
            chromosome.getQuestions().set(index, replacement);
        }
    }

    private void swapTwoQuestions(PaperChromosome chromosome) {
        if (chromosome.getQuestions().size() < 2) return;

        // 随机选择两道题目
        int index1 = (int) (Math.random() * chromosome.getQuestions().size());
        int index2;
        do {
            index2 = (int) (Math.random() * chromosome.getQuestions().size());
        } while (index1 == index2);

        // 交换
        Collections.swap(chromosome.getQuestions(), index1, index2);
    }

    private void adjustQuestionScores(PaperChromosome chromosome) {
        if (chromosome.getQuestions().isEmpty()) return;

        // 随机选择一道题目调整分数
        int index = (int) (Math.random() * chromosome.getQuestions().size());
        Question question = chromosome.getQuestions().get(index);

        // 随机调整分数(±0.5)
        double adjustment = (Math.random() - 0.5) * 2 * 0.5;
        BigDecimal newScore = question.getScore().add(BigDecimal.valueOf(adjustment))
                .max(BigDecimal.valueOf(0.5)); // 最低0.5分

        question.setScore(newScore);
    }

    // 其他辅助方法...
    private GeneticAlgorithmConfig getDefaultGAConfig(PaperStrategy strategy) {
        GeneticAlgorithmConfig config = new GeneticAlgorithmConfig();
        config.setPopulationSize(strategy.getPopulationSize());
        config.setMaxGenerations(strategy.getMaxGenerations());
        config.setMutationRate(strategy.getMutationRate().doubleValue());
        config.setCrossoverRate(strategy.getCrossoverRate().doubleValue());
        config.setFitnessThreshold(strategy.getFitnessThreshold().doubleValue());
        config.setTimeLimit(strategy.getTimeLimit());
        config.setDiversityThreshold(strategy.getDiversityThreshold().doubleValue());
        return config;
    }

    private PaperBO createPaperBO(PaperGenerateRequest request, List<Question> questions, Map<String, Object> config) {
        PaperBO paperBO = new PaperBO();
        paperBO.setTitle(request.getTitle());
        paperBO.setCode(request.getCode());

        // 计算总分
        BigDecimal totalScore = questions.stream()
                .map(Question::getScore)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        paperBO.setTotalScore(totalScore);

        // 设置及格分(默认为总分的60%)
        if (config.containsKey("passRate")) {
            double passRate = Double.parseDouble(config.get("passRate").toString());
            paperBO.setPassScore(totalScore.multiply(BigDecimal.valueOf(passRate)));
        } else {
            paperBO.setPassScore(totalScore.multiply(BigDecimal.valueOf(0.6)));
        }

        // 设置考试时长(默认为每题1分钟)
        if (config.containsKey("timePerQuestion")) {
            int timePerQuestion = Integer.parseInt(config.get("timePerQuestion").toString());
            paperBO.setTimeLimit(questions.size() * timePerQuestion);
        } else {
            paperBO.setTimeLimit(questions.size());
        }

        // 设置题目关联
        List<PaperQuestionBO> paperQuestions = new ArrayList<>();
        int sort = 1;
        for (Question question : questions) {
            PaperQuestionBO pq = new PaperQuestionBO();
            pq.setQuestionId(question.getId());
            pq.setScore(question.getScore());
            pq.setSort(sort++);
            pq.setRequired(1); // 默认必做
            paperQuestions.add(pq);
        }
        paperBO.setQuestions(paperQuestions);

        return paperBO;
    }

    private List<Question> selectQuestionsByTemplate(Map<String, Object> config) {
        // 解析模板配置
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> typeConfigs = (List<Map<String, Object>>) config.get("types");
        List<Long> categoryIds = config.containsKey("categories") ?
                (List<Long>) config.get("categories") : Collections.emptyList();
        List<Long> knowledgeIds = config.containsKey("knowledgePoints") ?
                (List<Long>) config.get("knowledgePoints") : Collections.emptyList();

        // 查询题目
        List<Question> allQuestions = new ArrayList<>();

        for (Map<String, Object> typeConfig : typeConfigs) {
            Long typeId = Long.valueOf((Integer) typeConfig.get("typeId"));
            String typeName = (String) typeConfig.get("name");
            int count = (int) typeConfig.get("count");
            BigDecimal score = new BigDecimal(typeConfig.get("score").toString());

            // 查询该题型的题目
            List<Question> typeQuestions = questionMapper.selectList(
                    Wrappers.<Question>lambdaQuery()
                            .eq(Question::getTypeId, typeId)
                            .eq(Question::getDelFlag, 0)
                            .eq(Question::getStatus, 1));

            // 过滤分类和知识点
            if (!categoryIds.isEmpty() || !knowledgeIds.isEmpty()) {
                typeQuestions = filterQuestionsByCategoriesAndKnowledge(typeQuestions, categoryIds, knowledgeIds);
            }

            // 随机选择指定数量的题目
            Collections.shuffle(typeQuestions);
            List<Question> selected = typeQuestions.subList(0, Math.min(count, typeQuestions.size()));

            // 设置题目分数
            selected.forEach(q -> q.setScore(score));
            allQuestions.addAll(selected);
        }

        return allQuestions;
    }

    @SuppressWarnings("unchecked")
    private List<Question> selectQuestionsByQuestionConfig(Map<String, Object> config) {
        // 解析题型配置
        List<Map<String, Object>> typeConfigs = (List<Map<String, Object>>) config.get("types");
        List<Long> categoryIds = config.containsKey("categories") ?
                (List<Long>) config.get("categories") : Collections.emptyList();
        List<Long> knowledgeIds = config.containsKey("knowledgePoints") ?
                (List<Long>) config.get("knowledgePoints") : Collections.emptyList();

        // 查询所有符合条件的题目
        List<Question> allQuestions = new ArrayList<>();

        for (Map<String, Object> typeConfig : typeConfigs) {
            Long typeId = Long.valueOf((Integer) typeConfig.get("typeId"));


            // 查询该题型的题目
            List<Question> typeQuestions = questionMapper.selectList(
                    PlusWrappers.lambdaQuery(Question.class)
                            .eq(Question::getTypeId, typeId)
                            .eq(Question::getDelFlag, 0)
            );

            // 过滤分类和知识点
            if (!categoryIds.isEmpty() || !knowledgeIds.isEmpty()) {
                typeQuestions = filterQuestionsByCategoriesAndKnowledge(typeQuestions, categoryIds, knowledgeIds);
            }

            allQuestions.addAll(typeQuestions);
        }

        return allQuestions;
    }

    private List<Question> filterQuestionsByCategoriesAndKnowledge(List<Question> questions,
                                                                   List<Long> categoryIds, List<Long> knowledgeIds) {

        if (questions.isEmpty()) {
            return questions;
        }

        List<Long> questionIds = questions.stream().map(Question::getId).collect(Collectors.toList());

        // 查询分类关联
        Map<Long, List<Long>> questionCategories;
        if (!categoryIds.isEmpty()) {
            List<QuestionCategoryRelation> categoryRelations = questionCategoryRelationMapper.selectList(
                    Wrappers.<QuestionCategoryRelation>lambdaQuery()
                            .in(QuestionCategoryRelation::getQuestionId, questionIds)
                            .in(QuestionCategoryRelation::getCategoryId, categoryIds)
                            .eq(QuestionCategoryRelation::getIsKnowledge, 0)
                            .eq(QuestionCategoryRelation::getDelFlag, 0));

            questionCategories = categoryRelations.stream()
                    .collect(Collectors.groupingBy(
                            QuestionCategoryRelation::getQuestionId,
                            Collectors.mapping(QuestionCategoryRelation::getCategoryId, Collectors.toList())
                    ));
        } else {
            questionCategories = new HashMap<>();
        }

        // 查询知识点关联
        Map<Long, List<Long>> questionKnowledges;
        if (!knowledgeIds.isEmpty()) {
            List<QuestionTagRelation> knowledgeRelations = questionTagRelationMapper.selectList(
                    Wrappers.<QuestionTagRelation>lambdaQuery()
                            .in(QuestionTagRelation::getQuestionId, questionIds)
                            .eq(QuestionTagRelation::getDelFlag, 0));

            questionKnowledges = knowledgeRelations.stream()
                    .collect(Collectors.groupingBy(
                            QuestionTagRelation::getQuestionId,
                            Collectors.mapping(QuestionTagRelation::getTagId, Collectors.toList())
                    ));
        } else {
            questionKnowledges = new HashMap<>();
        }

        // 过滤题目
        return questions.stream().filter(q -> {
            boolean passCategory = categoryIds.isEmpty() ||
                    !Collections.disjoint(questionCategories.getOrDefault(q.getId(), Collections.emptyList()), categoryIds);

            boolean passKnowledge = knowledgeIds.isEmpty() ||
                    !Collections.disjoint(questionKnowledges.getOrDefault(q.getId(), Collections.emptyList()), knowledgeIds);

            return passCategory && passKnowledge;
        }).collect(Collectors.toList());
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> parseTemplateConfig(String configJson) {
        try {
            return JSONUtil.parseObj(configJson);
        } catch (Exception e) {
            throw new ServiceException("模板配置解析失败");
        }
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> parseDifficultyConfig(String configJson) {
        try {
            return JSONUtil.parseObj(configJson);
        } catch (Exception e) {
            throw new ServiceException("难度配置解析失败");
        }
    }

    @SuppressWarnings("unchecked")
    private JSONObject parseKnowledgeConfig(String configJson) {
        try {
            return JSONUtil.parseObj(configJson);
        } catch (Exception e) {
            throw new ServiceException("知识点配置解析失败");
        }
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> parseQuestionConfig(String configJson) {
        try {
            return JSONUtil.parseObj(configJson);
        } catch (Exception e) {
            throw new ServiceException("题型配置解析失败");
        }
    }

    // 创建试卷(复用已有方法)
    private R<Long> createPaper(PaperBO paperBO) {
        // 验证试卷标题和编码
        if (StringUtils.isBlank(paperBO.getTitle())) {
            return R.fail("试卷标题不能为空");
        }

        if (StringUtils.isBlank(paperBO.getCode())) {
            return R.fail("试卷编码不能为空");
        }

        // 检查编码是否已存在
        if (paperMapper.exists(Wrappers.<Paper>lambdaQuery()
                .eq(Paper::getCode, paperBO.getCode())
                .eq(Paper::getDelFlag, 0))) {
            return R.fail("试卷编码已存在");
        }

        // 创建试卷
        Paper paper = BeanUtil.copyProperties(paperBO, Paper.class);
        paper.setStatus(0); // 草稿状态
        paper.setVersion(1);

        paperMapper.insert(paper);

        // 保存试卷题目关联
        savePaperQuestions(paper.getId(), paperBO.getQuestions());

        return R.ok(paper.getId());
    }

    private void savePaperQuestions(Long paperId, List<PaperQuestionBO> questions) {
        if (CollUtil.isEmpty(questions)) {
            return;
        }

        List<PaperQuestion> paperQuestions = questions.stream()
                .map(bo -> {
                    PaperQuestion pq = new PaperQuestion();
                    BeanUtils.copyProperties(bo, pq);
                    pq.setPaperId(paperId);
                    pq.setDelFlag(0);
                    return pq;
                })
                .collect(Collectors.toList());

        paperQuestionMapper.insertBatch(paperQuestions);

        // 更新题目统计信息
        updateQuestionStatistics(questions);
    }

    private void updateQuestionStatistics(List<PaperQuestionBO> questions) {
        List<Long> questionIds = questions.stream()
                .map(PaperQuestionBO::getQuestionId)
                .collect(Collectors.toList());

        if (CollUtil.isEmpty(questionIds)) {
            return;
        }

        // 批量更新题目统计信息
        questionStatisticsMapper.batchUpdatePaperCount(questionIds, SecurityUtils.getUserId());
    }
}